



<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#FFF">
  <link rel="apple-touch-icon" sizes="180x180" href="/blog/images/apple-touch-icon.png">

<link rel="icon" type="image/ico" sizes="32x32" href="/blog/images/favicon.ico">
  <meta http-equiv="Cache-Control" content="no-transform">
  <meta http-equiv="Cache-Control" content="no-siteapp">


<link rel="alternate" type="application/rss+xml" title="宋胖子" href="https://song-ruipeng.gitee.io/blog/rss.xml" />
<link rel="alternate" type="application/atom+xml" title="宋胖子" href="https://song-ruipeng.gitee.io/blog/atom.xml" />
<link rel="alternate" type="application/json" title="宋胖子" href="https://song-ruipeng.gitee.io/blog/feed.json" />

<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Mulish:300,300italic,400,400italic,700,700italic%7CFredericka%20the%20Great:300,300italic,400,400italic,700,700italic%7CNoto%20Serif%20JP:300,300italic,400,400italic,700,700italic%7CNoto%20Serif%20SC:300,300italic,400,400italic,700,700italic%7CInconsolata:300,300italic,400,400italic,700,700italic&display=swap&subset=latin,latin-ext">

<link rel="stylesheet" href="/blog/css/app.css?v=0.2.5">

  
  <meta name="keywords" content="少时诵诗书" />


<link rel="canonical" href="https://song-ruipeng.gitee.io/blog/2023/06/12/%E4%BA%94.template/">



  <title>
Template - 我的日志 |
Yume Shoka = 宋胖子</title>
<meta name="generator" content="Hexo 6.3.0"></head>
<body itemscope itemtype="http://schema.org/WebPage">
  <div id="loading">
    <div class="cat">
      <div class="body"></div>
      <div class="head">
        <div class="face"></div>
      </div>
      <div class="foot">
        <div class="tummy-end"></div>
        <div class="bottom"></div>
        <div class="legs left"></div>
        <div class="legs right"></div>
      </div>
      <div class="paw">
        <div class="hands left"></div>
        <div class="hands right"></div>
      </div>
    </div>
  </div>
  <div id="container">
    <header id="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="inner">
        <div id="brand">
          <div class="pjax">
          
  <h1 itemprop="name headline">Template
  </h1>
  
<div class="meta">
  <span class="item" title="创建时间：2023-06-12 21:02:00">
    <span class="icon">
      <i class="ic i-calendar"></i>
    </span>
    <span class="text">发表于</span>
    <time itemprop="dateCreated datePublished" datetime="2023-06-12T21:02:00+08:00">2023-06-12</time>
  </span>
</div>


          </div>
        </div>
        <nav id="nav">
  <div class="inner">
    <div class="toggle">
      <div class="lines" aria-label="切换导航栏">
        <span class="line"></span>
        <span class="line"></span>
        <span class="line"></span>
      </div>
    </div>
    <ul class="menu">
      <li class="item title"><a href="/blog/" rel="start">Yume Shoka</a></li>
    </ul>
    <ul class="right">
      <li class="item theme">
        <i class="ic i-sun"></i>
      </li>
      <li class="item search">
        <i class="ic i-search"></i>
      </li>
    </ul>
  </div>
</nav>

      </div>
      <div id="imgs" class="pjax">
        <ul>
          <li class="item" data-background-image=" https://cancan-wx.oss-cn-hangzhou.aliyuncs.com/bg/6833939bly1gipewkhf1zj20zk0m81kx.jpg"></li>
          <li class="item" data-background-image=" https://cancan-wx.oss-cn-hangzhou.aliyuncs.com/bg/6833939bly1gicis081o9j20zk0m8dmr.jpg"></li>
          <li class="item" data-background-image=" https://cancan-wx.oss-cn-hangzhou.aliyuncs.com/bg/6833939bly1gicitcxhpij20zk0m8hdt.jpg"></li>
          <li class="item" data-background-image=" https://cancan-wx.oss-cn-hangzhou.aliyuncs.com/bg/6833939bly1gipeyhsblkj20zk0m81kx.jpg"></li>
          <li class="item" data-background-image=" https://cancan-wx.oss-cn-hangzhou.aliyuncs.com/bg/6833939bly1gipeubcbajj20zk0m8h1h.jpg"></li>
          <li class="item" data-background-image=" https://cancan-wx.oss-cn-hangzhou.aliyuncs.com/bg/6833939bly1gipexe4oykj20zk0m87ji.jpg"></li>
        </ul>
      </div>
    </header>
    <div id="waves">
      <svg class="waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto">
        <defs>
          <path id="gentle-wave" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
        </defs>
        <g class="parallax">
          <use xlink:href="#gentle-wave" x="48" y="0" />
          <use xlink:href="#gentle-wave" x="48" y="3" />
          <use xlink:href="#gentle-wave" x="48" y="5" />
          <use xlink:href="#gentle-wave" x="48" y="7" />
        </g>
      </svg>
    </div>
    <main>
      <div class="inner">
        <div id="main" class="pjax">
          
  <div class="article wrap">
    
<div class="breadcrumb" itemscope itemtype="https://schema.org/BreadcrumbList">
<i class="ic i-home"></i>
<span><a href="/blog/">首页</a></span><i class="ic i-angle-right"></i>
<span  class="current" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" itemprop="item" rel="index" title="分类于 我的日志"><span itemprop="name">我的日志</span></a>
<meta itemprop="position" content="1" /></span>
</div>

    <article itemscope itemtype="http://schema.org/Article" class="post block" lang="zh-CN">
  <link itemprop="mainEntityOfPage" href="https://song-ruipeng.gitee.io/blog/2023/06/12/%E4%BA%94.template/">

  <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
    <meta itemprop="image" content="/blog/images/avatar.jpg">
    <meta itemprop="name" content="宋胖子">
    <meta itemprop="description" content=", 欢迎大家一起交流">
  </span>

  <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
    <meta itemprop="name" content="宋胖子">
  </span>

  <div class="body md" itemprop="articleBody">
    

    <h3 id="五template"><a class="markdownIt-Anchor" href="#五template">#</a> 五.Template</h3>
<h4 id="1解析阶段"><a class="markdownIt-Anchor" href="#1解析阶段">#</a> 1. 解析阶段</h4>
<pre><code>在这个阶段，Vue会将模版字符串收集起来，解析成AST(抽象语法树)的解构。解析器会扫描模版字符串，识别出其中的HTML标签，属性，表达式等内容，然后构建成一个抽象语法树。这个过程中也会对表达式进行解析和优化,以生成更高效的渲染函数。
</code></pre>
<p>E.m 例子如下：</p>
  <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span>&gt;</span>&#123;&#123; title &#125;&#125;<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">ul</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;item in items&quot;</span>&gt;</span>&#123;&#123; item &#125;&#125;<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>在解析阶段，Vue 将这个模板解析为 AST 的结构：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  type: &#x27;element&#x27;,</span><br><span class="line">  tag: &#x27;div&#x27;,</span><br><span class="line">  attrsList: [],</span><br><span class="line">  children: [</span><br><span class="line">    &#123;</span><br><span class="line">      type: &#x27;element&#x27;,</span><br><span class="line">      tag: &#x27;h1&#x27;,</span><br><span class="line">      attrsList: [],</span><br><span class="line">      children: [&#123; type: &#x27;expression&#x27;, expression: &#x27;title&#x27; &#125;]</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      type: &#x27;element&#x27;,</span><br><span class="line">      tag: &#x27;ul&#x27;,</span><br><span class="line">      attrsList: [],</span><br><span class="line">      children: [</span><br><span class="line">        &#123;</span><br><span class="line">          type: &#x27;element&#x27;,</span><br><span class="line">          tag: &#x27;li&#x27;,</span><br><span class="line">          attrsList: [&#123; name: &#x27;v-for&#x27;, value: &#x27;item in items&#x27; &#125;],</span><br><span class="line">          children: [&#123; type: &#x27;expression&#x27;, expression: &#x27;item&#x27; &#125;]</span><br><span class="line">        &#125;</span><br><span class="line">      ]</span><br><span class="line">    &#125;</span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="2代码生成阶段"><a class="markdownIt-Anchor" href="#2代码生成阶段">#</a> 2. 代码生成阶段</h4>
<p>在这个阶段，Vue 将 AST 转换为渲染函数（render 函数）。渲染函数是一个 JS 函数，它接收一个上下文对象作为参数，并返回一个 VNode（虚拟节点）对象，表示要渲染的 DOM 树结构。在渲染函数中，Vue 会将模板中的 HTML 标签转换为 <strong>createElement</strong> 函数调用，将指令和表达式转换为相应的 JavaScript 代码。<br>
例如，对于上面的模板，生成的渲染函数大致如下：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">render</span>(<span class="params">_ctx, _cache</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="title function_">_openBlock</span>(), <span class="title function_">_createBlock</span>(<span class="string">&quot;div&quot;</span>, <span class="literal">null</span>, [</span><br><span class="line">    <span class="title function_">_createVNode</span>(<span class="string">&quot;h1&quot;</span>, <span class="literal">null</span>, <span class="title function_">_toDisplayString</span>(_ctx.<span class="property">title</span>), <span class="number">1</span> <span class="comment">/* TEXT */</span>),</span><br><span class="line">    <span class="title function_">_createVNode</span>(<span class="string">&quot;ul&quot;</span>, <span class="literal">null</span>, [</span><br><span class="line">      (_cache[item] || (_cache[item] = <span class="title function_">_withDirectives</span>((<span class="title function_">_openBlock</span>(), <span class="title function_">_createBlock</span>(<span class="string">&quot;li&quot;</span>, &#123;</span><br><span class="line">        <span class="attr">key</span>: item</span><br><span class="line">      &#125;, <span class="title function_">_toDisplayString</span>(item), <span class="number">1</span> <span class="comment">/* TEXT */</span>)), [[_directive_resolveModel, _ctx.<span class="property">items</span>, item]])))</span><br><span class="line">    ])</span><br><span class="line">  ])</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>在上面的渲染函数中，我们可以看到通过调用 Vue 提供的 <strong>_createVNode</strong> 函数和 <strong>_createBlock</strong> 函数来创建虚拟节点，并使用_toDisplayString 函数来将表达式的值转换为字符串。同时，在循环中使用了_cache 对象来缓存已渲染的 VNode，以提高渲染性能。</p>
<pre><code> 总的来说，Vue的模板编译过程将模板字符串转换为一个JavaScript函数，该函数接收一个上下文对象作为参数，并返回一个VNode对象，表示要渲染的DOM树结构。这个过程中，Vue将模板中的HTML标记和指令转换为JavaScript函数调用，同时对表达式进行解析和优化，以生成更高效的渲染函数。
</code></pre>
<h4 id="3执行渲染函数"><a class="markdownIt-Anchor" href="#3执行渲染函数">#</a> 3. 执行渲染函数</h4>
<p>经过上面两个步骤我们已经将模板解析并生成了渲染函数了，接下来 Vue 又是如何执行渲染函数的呢？<br>
在 Vue 中，执行渲染函数的过程是通过调用虚拟 DOM 的 patch 方法来实现的。patch 方法接收两个参数，一个是旧 VNode，另一个是新 VNode。它会比较这两个 VNode 的差异，并将差异应用到真实的 DOM 上。<br>
在组件初始化或数据更新时，Vue 会生成新的 VNode 并与旧的 VNode 进行比较，找出两者之间的差异，并将这些差异应用到真实的 DOM 上。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- <span class="title class_">App</span>.<span class="property">vue</span> --&gt;</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">button</span> @<span class="attr">click</span>=<span class="string">&quot;increment&quot;</span>&gt;</span>&#123;&#123; count &#125;&#125;<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title function_">data</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">count</span>: <span class="number">0</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">methods</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title function_">increment</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.<span class="property">count</span>++</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> <span class="title function_">h</span>(<span class="string">&#x27;div&#x27;</span>, [</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="title function_">h</span>(<span class="string">&#x27;button&#x27;</span>, &#123; <span class="attr">on</span>: &#123; <span class="attr">click</span>: <span class="variable language_">this</span>.<span class="property">increment</span> &#125; &#125;, <span class="variable language_">this</span>.<span class="property">count</span>)</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    ])</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<p>在上面的代码中，我们使用 render 函数来创建 VNode 树，并返回一个根节点。在这个例子中， 函数 render 里的 h 函数是 Vue 提供的用于创建 VNode 的辅助函数。<br>
在这个例子中，如果用户点击了按钮，Vue 将会重新调用 render 函数，并返回一个更新后的 VNode 树。然后，Vue 将会将这个 VNode 树与之前的 VNode 树进行比较，并计算出需要对 DOM 进行的更改。这些更改将被传递给虚拟 DOM 的 patch 方法，该方法将这些更改应用到真实的 DOM 上，从而实现更新视图的效果。<br>
这里只是一个简单的示例，实际上，渲染函数可能更加复杂，可以使用计算属性、循环等功能来实现更加强大的动态 UI。但是无论如何，渲染函数的基本原理都是通过比较新旧 VNode 的差异，并将这些差异应用到真实的 DOM 上来实现更新视图的效果。<br>
这个示例的过程就像我们在玩扑克牌时，每个玩家手中拥有一些牌，需要不断地调整牌的位置，直到得到最优的牌型。<br>
假设我们有两个玩家 A 和 B，他们各自手中有 5 张牌，每次玩家 A 会换掉一张手牌，然后将手牌展示给所有玩家看。其他玩家可以观察 A 的换牌过程，然后根据 A 的牌型和其他玩家手中的牌来决定自己是否换牌。<br>
在这个过程中，A 换掉牌相当于更新了数据，其他玩家观察 A 换牌的过程相当于生成新的虚拟 DOM 树，然后根据新旧虚拟 DOM 树的变化来决定是否更新视图。每个玩家都可以通过观察 A 换牌的过程来得到最新的牌型和最优的决策。<br>
类比到 Vue 中，每个组件都有自己的数据，当数据发生变化时，Vue 会根据渲染函数生成新的虚拟 DOM 树，然后通过比对新旧虚拟 DOM 树来判断哪些节点需要更新。最终，Vue 会将更新的节点通过 DOM 操作更新到视图上，让用户看到最新的内容。</p>
<h4 id="4-对比新旧virtual-dom树"><a class="markdownIt-Anchor" href="#4-对比新旧virtual-dom树">#</a> 4、对比新旧 Virtual DOM 树</h4>
<p>上面我们说到 Vue 会根据渲染函数生成新的虚拟 DOM 树，然后通过比对新旧虚拟 DOM 树来判断哪些节点需要更新。那 Vue 又是通过什么来做这个判断的呢？答案就是 Virtual DOM Diff 算法。<br>
Vue 的 Virtual DOM Diff 算法是一个用于比较新旧 Virtual DOM 树之间差异的算法。它通过对比两棵树的节点，找到需要更新、添加和删除的节点，然后对真实 DOM 进行最小化的操作。<br>
Vue 的 Diff 算法可以大致分为以下三个步骤：<br>
首先比较新旧 Virtual DOM 的根节点，如果它们的标签名、key 和属性都相同，则认为这两个节点是相同的，可以直接比较它们的子节点。如果根节点不同，则直接将新的 Virtual DOM 替换旧的 Virtual DOM。<br>
对比子节点，通过遍历新旧 Virtual DOM 树的子节点列表，按顺序进行比较。Vue 使用了一些启发式的策略来尽可能地减少比较次数，例如只对同级节点进行比较，通过节点的 key 来快速定位到相同的节点等。在比较过程中，如果有子节点不同，就将新的子节点插入到旧的子节点的位置上，然后递归对新旧子节点进行比较。<br>
对比完成后，得到了需要更新、添加和删除的节点，Vue 会将这些操作打包成一个补丁（patch），然后将补丁应用到真实 DOM 上，从而完成更新。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">h1</span>&gt;</span>&#123;&#123; title &#125;&#125;<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;item in items&quot;</span> <span class="attr">:key</span>=<span class="string">&quot;item.id&quot;</span>&gt;</span>&#123;&#123; item.text &#125;&#125;<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title function_">data</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">title</span>: <span class="string">&#x27;Todo List&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">items</span>: [</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#123; <span class="attr">id</span>: <span class="number">1</span>, <span class="attr">text</span>: <span class="string">&#x27;Learn Vue&#x27;</span> &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#123; <span class="attr">id</span>: <span class="number">2</span>, <span class="attr">text</span>: <span class="string">&#x27;Build an app&#x27;</span> &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#123; <span class="attr">id</span>: <span class="number">3</span>, <span class="attr">text</span>: <span class="string">&#x27;Deploy to production&#x27;</span> &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      ],</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">methods</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title function_">addItem</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.<span class="property">items</span>.<span class="title function_">push</span>(&#123; <span class="attr">id</span>: <span class="number">4</span>, <span class="attr">text</span>: <span class="string">&#x27;Test&#x27;</span> &#125;);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>在这个例子中，当调用 addItem 方法添加新的 item 时，Vue 会重新执行渲染函数，生成一个新的 Virtual DOM 树。Vue 会对比新旧 Virtual DOM 树的差异，并将差异应用到真实的 DOM 树上，从而实现高效的更新。<br>
Vue2 和 Vue3 的 Virtual DOM Diff 算法有一些不同之处，Vue3 对 Diff 算法进行了一些优化，以提高渲染性能和减少内存占用。下面分别介绍 Vue2 和 Vue3 的 Diff 算法。</p>

      <div class="tags">
          <a href="/blog/tags/%E5%B0%91%E6%97%B6%E8%AF%B5%E8%AF%97%E4%B9%A6/" rel="tag"><i class="ic i-tag"></i> 少时诵诗书</a>
      </div>
  </div>

   <footer>

    <div class="meta">
  <span class="item">
    <span class="icon">
      <i class="ic i-calendar-check"></i>
    </span>
    <span class="text">更新于</span>
    <time title="修改时间：2023-08-06 15:14:19" itemprop="dateModified" datetime="2023-08-06T15:14:19+08:00">2023-08-06</time>
  </span>
</div>

      
<div class="reward">
  <button><i class="ic i-heartbeat"></i> 赞赏</button>
  <p>请我喝[茶]~(￣▽￣)~*</p>
  <div id="qr">
      
      <div>
        <img data-src="/blog/images/wechatpay.png" alt="宋胖子 微信支付">
        <p>微信支付</p>
      </div>
      
      <div>
        <img data-src="/blog/images/alipay.png" alt="宋胖子 支付宝">
        <p>支付宝</p>
      </div>
      
      <div>
        <img data-src="/blog/images/paypal.png" alt="宋胖子 贝宝">
        <p>贝宝</p>
      </div>
  </div>
</div>

      

<div id="copyright">
<ul>
  <li class="author">
    <strong>本文作者： </strong>宋胖子 <i class="ic i-at"><em>@</em></i>宋胖子
  </li>
  <li class="link">
    <strong>本文链接：</strong>
    <a href="https://song-ruipeng.gitee.io/blog/2023/06/12/%E4%BA%94.template/" title="Template">https://song-ruipeng.gitee.io/blog/2023/06/12/五.template/</a>
  </li>
  <li class="license">
    <strong>版权声明： </strong>本站所有文章除特别声明外，均采用 <span class="exturl" data-url="aHR0cHM6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LW5jLXNhLzQuMC9kZWVkLnpo"><i class="ic i-creative-commons"><em>(CC)</em></i>BY-NC-SA</span> 许可协议。转载请注明出处！
  </li>
</ul>
</div>

  </footer>

</article>

  </div>
  

<div class="post-nav">
    <div class="item left">
      

  <a href="/blog/2023/05/17/%E5%9B%9B.JS/" itemprop="url" rel="prev" data-background-image=" https:&#x2F;&#x2F;cancan-wx.oss-cn-hangzhou.aliyuncs.com&#x2F;bg&#x2F;6833939bly1gipetv6p75j20zk0m8x6p.jpg" title="JS">
  <span class="type">上一篇</span>
  <span class="category"><i class="ic i-flag"></i> 我的日志</span>
  <h3>JS</h3>
  </a>

    </div>
    <div class="item right">
      

  <a href="/blog/2023/07/03/%C2%A0%E5%85%AD.%E8%AF%BB%E6%BA%90%E7%A0%81%E7%90%86%E8%A7%A3Vnode/" itemprop="url" rel="next" data-background-image=" https:&#x2F;&#x2F;cancan-wx.oss-cn-hangzhou.aliyuncs.com&#x2F;bg&#x2F;6833939bly1gipewf5l51j20zk0m8b29.jpg" title="读源码理解Vnode">
  <span class="type">下一篇</span>
  <span class="category"><i class="ic i-flag"></i> 我的日志</span>
  <h3>读源码理解Vnode</h3>
  </a>

    </div>
</div>

  
  <div class="wrap" id="comments"></div>


        </div>
        <div id="sidebar">
          

<div class="inner">

  <div class="panels">
    <div class="inner">
      <div class="contents panel pjax" data-title="文章目录">
          <ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BA%94template"><span class="toc-number">1.</span> <span class="toc-text"> 五.Template</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#1%E8%A7%A3%E6%9E%90%E9%98%B6%E6%AE%B5"><span class="toc-number">1.1.</span> <span class="toc-text"> 1. 解析阶段</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90%E9%98%B6%E6%AE%B5"><span class="toc-number">1.2.</span> <span class="toc-text"> 2. 代码生成阶段</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3%E6%89%A7%E8%A1%8C%E6%B8%B2%E6%9F%93%E5%87%BD%E6%95%B0"><span class="toc-number">1.3.</span> <span class="toc-text"> 3. 执行渲染函数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#4-%E5%AF%B9%E6%AF%94%E6%96%B0%E6%97%A7virtual-dom%E6%A0%91"><span class="toc-number">1.4.</span> <span class="toc-text"> 4、对比新旧 Virtual DOM 树</span></a></li></ol></li></ol>
      </div>
      <div class="related panel pjax" data-title="系列文章">
        <ul>
          <li><a href="/blog/2022/08/20/%E4%B9%9D.Vue/" rel="bookmark" title="vue总结">vue总结</a></li><li><a href="/blog/2023/04/18/%E5%8D%81.HTTP/" rel="bookmark" title="HTTP总结">HTTP总结</a></li><li><a href="/blog/2023/04/18/%E4%B8%80.%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80%E6%80%BB%E7%BB%93/" rel="bookmark" title="计算机网络基础总结">计算机网络基础总结</a></li><li><a href="/blog/2023/04/21/%E4%BA%8C.Event%20Loop/" rel="bookmark" title="Event Loop">Event Loop</a></li><li><a href="/blog/2023/05/05/%E4%B8%89.Css/" rel="bookmark" title="CSS">CSS</a></li><li><a href="/blog/2023/05/17/%E5%9B%9B.JS/" rel="bookmark" title="JS">JS</a></li><li class="active"><a href="/blog/2023/06/12/%E4%BA%94.template/" rel="bookmark" title="Template">Template</a></li><li><a href="/blog/2023/07/03/%C2%A0%E5%85%AD.%E8%AF%BB%E6%BA%90%E7%A0%81%E7%90%86%E8%A7%A3Vnode/" rel="bookmark" title="读源码理解Vnode">读源码理解Vnode</a></li><li><a href="/blog/2023/07/18/%E4%B8%83.React/" rel="bookmark" title="React">React</a></li><li><a href="/blog/2023/07/20/%E5%85%AB.%E8%AF%BB%E3%80%8AVuejs%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%AE%9E%E7%8E%B0%E3%80%8B%E6%80%BB%E7%BB%93/" rel="bookmark" title="读《Vuejs设计与实现》总结">读《Vuejs设计与实现》总结</a></li><li><a href="/blog/2023/07/25/%E4%B9%9D.React%E9%9D%A2%E8%AF%95/" rel="bookmark" title="React面试">React面试</a></li><li><a href="/blog/2023/07/25/%E5%8D%81%E4%B8%80.%E8%87%AA%E6%B5%8B1/" rel="bookmark" title="自测1">自测1</a></li><li><a href="/blog/2023/08/15/%E5%8D%81%E4%BA%8C.Supense%E5%92%8C%E5%BC%82%E6%AD%A5%E7%BB%84%E4%BB%B6%E8%A7%A3%E5%86%B3%E9%A6%96%E9%A1%B5%E7%99%BD%E5%B1%8F%E9%97%AE%E9%A2%98/" rel="bookmark" title="Supense和异步组件解决首页白屏问题">Supense和异步组件解决首页白屏问题</a></li>
        </ul>
      </div>
      <div class="overview panel" data-title="站点概览">
        <div class="author" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <img class="image" itemprop="image" alt="宋胖子"
      data-src="/blog/images/avatar.jpg">
  <p class="name" itemprop="name">宋胖子</p>
  <div class="description" itemprop="description">欢迎大家一起交流</div>
</div>

<nav class="state">
    <div class="item posts">
      <a href="/blog/archives/">
        <span class="count">13</span>
        <span class="name">文章</span>
      </a>
    </div>
    <div class="item categories">
      <a href="/blog/categories/">
        <span class="count">1</span>
        <span class="name">分类</span>
      </a>
    </div>
    <div class="item tags">
      <a href="/blog/tags/">
        <span class="count">1</span>
        <span class="name">标签</span>
      </a>
    </div>
</nav>

<div class="social">
</div>

<ul class="menu">
  
    
  <li class="item">
    <a href="/blog/" rel="section"><i class="ic i-home"></i>首页</a>
  </li>


</ul>

      </div>
    </div>
  </div>

  <ul id="quick">
    <li class="prev pjax">
        <a href="/blog/2023/05/17/%E5%9B%9B.JS/" rel="prev" title="上一篇"><i class="ic i-chevron-left"></i></a>
    </li>
    <li class="up"><i class="ic i-arrow-up"></i></li>
    <li class="down"><i class="ic i-arrow-down"></i></li>
    <li class="next pjax">
        <a href="/blog/2023/07/03/%C2%A0%E5%85%AD.%E8%AF%BB%E6%BA%90%E7%A0%81%E7%90%86%E8%A7%A3Vnode/" rel="next" title="下一篇"><i class="ic i-chevron-right"></i></a>
    </li>
    <li class="percent"></li>
  </ul>
</div>


        </div>
        <div class="dimmer"></div>
      </div>
    </main>
    <footer id="footer">
      <div class="inner">
        <div class="widgets">
          
<div class="rpost pjax">
  <h2>随机文章</h2>
  <ul>
      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/07/03/%C2%A0%E5%85%AD.%E8%AF%BB%E6%BA%90%E7%A0%81%E7%90%86%E8%A7%A3Vnode/" title="读源码理解Vnode">读源码理解Vnode</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/04/18/%E5%8D%81.HTTP/" title="HTTP总结">HTTP总结</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/07/25/%E5%8D%81%E4%B8%80.%E8%87%AA%E6%B5%8B1/" title="自测1">自测1</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/07/25/%E4%B9%9D.React%E9%9D%A2%E8%AF%95/" title="React面试">React面试</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/04/18/%E4%B8%80.%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80%E6%80%BB%E7%BB%93/" title="计算机网络基础总结">计算机网络基础总结</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/06/12/%E4%BA%94.template/" title="Template">Template</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2022/08/20/%E4%B9%9D.Vue/" title="vue总结">vue总结</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/05/05/%E4%B8%89.Css/" title="CSS">CSS</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/04/21/%E4%BA%8C.Event%20Loop/" title="Event Loop">Event Loop</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/08/15/%E5%8D%81%E4%BA%8C.Supense%E5%92%8C%E5%BC%82%E6%AD%A5%E7%BB%84%E4%BB%B6%E8%A7%A3%E5%86%B3%E9%A6%96%E9%A1%B5%E7%99%BD%E5%B1%8F%E9%97%AE%E9%A2%98/" title="Supense和异步组件解决首页白屏问题">Supense和异步组件解决首页白屏问题</a></span>
  </li>

  </ul>
</div>
<div>
  <h2>最新评论</h2>
  <ul class="leancloud-recent-comment"></ul>
</div>

        </div>
        <div class="status">
  <div class="copyright">
    
    &copy; 2010 – 
    <span itemprop="copyrightYear">2023</span>
    <span class="with-love">
      <i class="ic i-sakura rotate"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">宋胖子 @ Yume Shoka</span>
  </div>
  <div class="powered-by">
    基于 <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlv">Hexo</span> & Theme.<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2FtZWhpbWUvaGV4by10aGVtZS1zaG9rYQ==">Shoka</span>
  </div>
</div>

      </div>
    </footer>
  </div>
<script data-config type="text/javascript">
  var LOCAL = {
    path: '2023/06/12/五.template/',
    favicon: {
      show: "（●´3｀●）やれやれだぜ",
      hide: "(´Д｀)大変だ！"
    },
    search : {
      placeholder: "文章搜索",
      empty: "关于 「 ${query} 」，什么也没搜到",
      stats: "${time} ms 内找到 ${hits} 条结果"
    },
    valine: true,fancybox: true,
    copyright: '复制成功，转载请遵守 <i class="ic i-creative-commons"></i>BY-NC-SA 协议。',
    ignores : [
      function(uri) {
        return uri.includes('#');
      },
      function(uri) {
        return new RegExp(LOCAL.path+"$").test(uri);
      }
    ]
  };
</script>

<script src="https://cdn.polyfill.io/v2/polyfill.js"></script>

<script src="//cdn.jsdelivr.net/combine/npm/pace-js@1.0.2/pace.min.js,npm/pjax@0.2.8/pjax.min.js,npm/whatwg-fetch@3.4.0/dist/fetch.umd.min.js,npm/animejs@3.2.0/lib/anime.min.js,npm/algoliasearch@4/dist/algoliasearch-lite.umd.js,npm/instantsearch.js@4/dist/instantsearch.production.min.js,npm/lozad@1/dist/lozad.min.js,npm/quicklink@2/dist/quicklink.umd.js"></script>

<script src="/blog/js/app.js?v=0.2.5"></script>




</body>
</html>
